/*
 * Funambol is a mobile platform developed by Funambol, Inc. 
 * Copyright (C) 2008 Funambol, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission 
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License 
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 * 
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably 
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#ifndef INCL_FUN_TIME_UTILS
#define INCL_FUN_TIME_UTILS

#include "base/util/StringBuffer.h"
#include "base/Log.h"
#include "CoreFoundation/CoreFoundation.h"
// #include "Date.h"

class Date;
class Timezone;

using namespace Funambol;

/**
 * It returns the current timezone on the device. It is used
 * to be inserted in the Date if there is no timezone set. The timezone
 * it the identifier of Olson table
 */
StringBuffer getCurrentTimezone();

/**
* Functions that has to be shared with the objective-c language. 
* Used to convert the date from the db into the string of the event
*/
StringBuffer convertAppleDateToStandard(long value, bool isAllDay, bool convertUTC = true);
StringBuffer convertAppleDateToStandard(const char* d, bool isAllDay, bool convertUTC = true) ;

StringBuffer convertStandardToAppleDate(Date& date, bool localMidnight = false);

void normalizeForAllDay(Date& dtmp, bool allDay);

NSDate* getAppleDateValue(Date& date);

NSDate* getMidnightDate(NSDate* date, Timezone& tz, bool utc = false);
NSDate* getEndOfTheDay (NSDate* date, Timezone& tz, bool utc = false);
NSDate* calculateBorderDay(NSDate* date, Timezone& tz, int when, bool utc);

/**
 * It needs to add a numberOfYear year to the existing one retrieved
 * by the current date
 */
long addYearToAppleDate(long day, int numberOfYear);


/**
 * Retrieves the number of days between two dates (in long format)
 */
long getNumberOfDaysByDates(long startdate, long enddate, Timezone& tz);

/**
 * Retrieve the number of months between two dates
 */
long getNumberOfMonthsByDates(long startdate, long enddate, Timezone& tz);

/**
 * return the new date in long format that has day added 
 */
long addDaysToDate(long date, Timezone& tz, int days);

/**
 * return the new date in long format that has months added 
 */
long addMonthsToDate(long date, Timezone& tz, int months);

/**
 * return the new date in long format that has years added 
 */
long addYearsToDate(long date, Timezone& tz, int years);

/**
 * Returns the day of week from a date in Apple format (a long value)
 */
long getDayOfWeekFromAppleDate(long value);

/**
 * Returns the day of the week from a date starting from a standard date format
 * YYYYMMDDYHHmmss(Z)
 */
long getDayOfWeekFromStandardDate(Date& value);

/**
 * Used the same convention used for windows plugin for the day of week mask
 * iphone uses 1=sun, 2=mon, 3=tue, 4=wed, 5=thu, 6=fri, 7=sat
 * windows is  1=sun, 2=mon, 4=tue, 8=wed, 16=thu, 32=fri, 64=sat
 */
long convertDayofWeekFromAppleToStandard(long day);

/**
 * As before it convert form the conventional value to the one apple wants
 * iphone uses 1=sun, 2=mon, 3=tue, 4=wed, 5=thu, 6=fri, 7=sat
 * windows is  1=sun, 2=mon, 4=tue, 8=wed, 16=thu, 32=fri, 64=sat
 */ 
long convertDayofWeekFromStandardToApple(long day);
    
/**
 * As before it convert form the conventional value to the one apple wants
 * iphone uses 1=sun, 2=mon, 3=tue, 4=wed, 5=thu, 6=fri, 7=sat
 * windows is  1=sun, 2=mon, 4=tue, 8=wed, 16=thu, 32=fri, 64=sat
 */ 
long getDayOfMonthFromAppleDate(long value);

/**
 * Get the day of month starting form a standard date value and format 
 * YYYYMMDDTHHmmss(Z)
 */
long getDayOfMonthFromStandardDate(Date& value);

/**
 * Get the week day from a date (usually to be supposed the date is in local time
 * Due to select value, the returned could be 
 * - select = 0: a day of week (1=SUN, 2=MON, 3=TUE...)  
 * - select = 1: a day of month (19, 15...)
 * - select = 2: a month ofyear (1=JAN, 2=FEB, 3=MAR...)
 * The function is called using the other two useful method
 */
long getValueFromAppleDate(long value, int select);

/**
 * Get the day of the week from a date (usually to be supposed the date is in local time)
 * the value returned is 1 for sunday, 2 for monday 3 for tuesday...
 */
long getDayOfWeekFromAppleDate(long value);

/**
 * Get the day of the month from a date (usually to be supposed the date is in local time)
 * the returned values are 1,2,3....
 */
long getDayOfMonthFromAppleDate(long value);

/**
 * Get the month of the year from a date (usually to be supposed the date is in local time)
 * a month of year (1=JAN, 2=FEB, 3=MAR)
 */
long getMonthOfYearFromAppleDate(long value);

/**
 * Get the year from the date retrieved from the value 
 */
long getYearFromAppleDate(long value);

/**
 * Get a long value starting form a Date containing the string yyyymmddThhmmss
 * that is the apple value of date, according to the timezone in the date
 */
long getAppleDateValueFromStandard(Date& date);

/**
 * To get the date at the local midnight that is used to get the
 * list of dates that are used in the recurring list to populate the 
 * Recurrence.day list
 * 
 */
long getLocalMidnightAppleDate(long value, Timezone& tz);

/**
 * It is used to calculate the end day in the recurrence
 * that end date value. It calculates the 23.59 of the same day
 */
long getDateEndRecurrence(long endDayRec, Timezone& tz);

/**
 * Fill all the needed fields to complete the timezone object.
 * @param val - the value retrieved from the iphone database
 * @param standardDate - [out] the field that will contain the date in local time formatter as 20080329T020000
 * @param daylightDate - [out] the field that will contain the date in local time formatter as 20081003T030000
 * @param offset - [out] it will contain the offset of that timezone
 *
 * @return true if all is ok, false otherwise (i.e. the timezone is not found with the name...)
 */
bool getTimezoneInfo(long year, const char* t, StringBuffer& standardDate, StringBuffer& daylightDate, 
                            long* standardOffset, long* daylightOffset, long* onlyOffset);


/**
 * The name of the timezone should follow the Olson ID that can be undestood by the 
 * NSTimeZone object
 */
bool checkValidTimezone(const char* t);

/**
 * Returns the number of days that are in the month given the month and the year
 */
int getNumberOfMonthDays(long month, long year);

NSDateComponents* getDateComponentsFromDate1970(long date);

#endif


